Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add first group support #179

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Add first group support #179

wants to merge 5 commits into from

Conversation

tinloaf
Copy link

@tinloaf tinloaf commented Mar 12, 2018

This adds the first elements of the new groups API to the SDK. A couple of things:

  • Major Caveat: The question of which changes in groups cause an event to appear at the "/sync" API endpoint still seems to be unclear. Therefore, the current implementation does not use events at all, but polls the API endpoints every time some information is requested. I've but big warnings into the docstrings that the respective methods do not cache, and that you should not overuse them.

  • I've also put warnings everywhere that the API is still unstable and may break at any time.

@non-Jedi non-Jedi self-requested a review March 12, 2018 23:37
@non-Jedi
Copy link
Collaborator

@tinloaf Thanks! This has been added to my todo list. Any chance of some tests at least for the non-api.py parts?

@tinloaf
Copy link
Author

tinloaf commented Mar 13, 2018

Yes, that's on my todo list. ;-) However, since the API is not yet really well-documented, writing the tests according to the (non-existent) Spec is somewhat difficult.

I actually wondered whether it would be possible to have Travis install and spin up a fresh synapse installation for every test, and then test against synapse… This would certainly slow testing down, but it would make everything testable. For local (i.e., non-travis) tests, you would have to start your own synapse instance then… But maybe those tests could be optional?

@tinloaf
Copy link
Author

tinloaf commented Mar 16, 2018

@non-Jedi I've added tests (well, if you want to call them that…) for the api.py part. The non-api.py part does currently not really do anything, because it is not yet clear how events for groups look like - therefore, there is no "event handling". In other words: All the client methods basically directly hit the API. It doesn't really make too much sense to test that, does it?

@non-Jedi
Copy link
Collaborator

Heh. I haven't looked at it closely yet, but you're thinking of it exactly
opposite me. To me, because the spec isn't stable it doesn't make sense to test
the api since it might change under us, but we could test the interface we
provide. Really, though we probably can't test much of anything in a really
useful way. It's not like the interface we provide is independent of the api, so
I totally see where you're coming from here.

I think in general we should make an effort to test even parts of the sdk using
unstable stuff on the theory that it's easier to rewrite tests than to write
tests from scratch for a piece of code that you didn't even write.

| group.
group_id (str): The group ID
"""
self._send("POST", "/groups/{}/profile".format(quote(group_id)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a return here. see #167

quote(group_id)))

def publicise_group(self, group_id, make_public):
"""Leave a group.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this docstring is wrong.

@non-Jedi non-Jedi self-assigned this May 21, 2018
Copy link
Collaborator

@non-Jedi non-Jedi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the thorough tests on this one. Biggest thing to me is getting rid of MatrixClient.get_groups and pulling info about invites/joins/leaves from sync.

body = {
"localpart": localpart
}
return self._send("POST", "/create_group", body)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All apis that haven't made it into the official spec yet should be called under the "unstable" api prefix. Believe it is /_matrix/client/unstable.

"""Update the profile of a group.

Args:
profile_data (dict): The request payload.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to make this 4 separate arguments? name, avatar_url, short_description, and long_description?


| name (string): The new name of the group

| avatar_url (URL): A URL pointing to the new URL for the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should explicitly state that this is an mxc url.

@@ -290,6 +309,21 @@ def get_rooms(self):
"""
return self.rooms

def get_groups(self):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the approach different here than for rooms? Can't we just make it a requirement that get_groups returns nothing meaningful if a sync hasn't yet completed?

If so, we shouldn't introduce this method at all since we're currently deprecating get_rooms.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just read through the groups docs, and I see that they don't specify anywhere
what groups stuff looks like coming down /sync. Nevertheless, group info does
come down /sync, and looks like:

{'leave': {},
 'join': {},
 'invite': {'+test:thebeckmeyers.xyz': {'profile': {'avatar_url': None,
    'name': 'test'},
   'inviter': '@adam:thebeckmeyers.xyz'}}}

Even though it isn't written down anywhere, I'd like to use the info from
/sync rather than introducing a completely separate polling function. We'll
just have to revisit if this changes in the future.

[ user_id ]: List of user IDs of the users in the group.
"""
response = self.client.api.get_users_in_group(self.group_id)
return [event["user_id"] for event in response["chunk"]]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we (should we?) return a list of User objects instead of a list of strings here (and elsewhere in class)?

Returns:
boolean: True if the room was added.
"""
if isinstance(room_id, Room):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mention that argument can be Room object as well as string in docstring? Should we make methods that take a user_id argument function in the same way with User objects?

else:
print("Check your server details are correct.")
sys.exit(2)
except MissingSchema as e:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be catching this error from requests since requests is supposed to be an implementation detail. I'll file an issue...

response = self.client.api.get_rooms_in_group(self.group_id)
return [event["room_id"] for event in response["chunk"]]

@property
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're already doing this with some fields, why not change the get_rooms method to rooms and add a @property decorator?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants